# 导入所需的库
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt


plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']#  指定字体为Microsoft YaHei（微软雅黑） ,
# 读取数据文件
df = pd.read_excel("All_TV.xls")

# 查看数据概况
print(df.info())

# 查看数据前五行
print(df.head())

# 数据清理
# 去除缺失数据
df = df.dropna()

# 将国家名称转换为小写
df['出品地'] = df['出品地'].str.lower()

# 将电视剧标签转换为列表类型
df['类型'] = df['类型'].apply(eval)

# 将导演和主演转换为列表类型，并去除空格
df['导演'] = df['导演'].apply(eval).apply(lambda x: [s.strip() for s in x])
df['主演'] = df['主演'].apply(eval).apply(lambda x: [s.strip() for s in x])

# 将出品时间转换为整数类型
df['出品时间'] = df['出品时间'].astype(int)

# 查看清理后的数据
print(df.info())
print(df.head())


# 查看数据概况
print(df.info())

# 查看数据前五行
print(df.head())




# 计算电视剧的平均评分
mean_rate = df["rate"].mean()
print(f"电视剧的平均评分是{mean_rate:.2f}")

# 计算每个出品地的电视剧数量
country_count = df["出品地"].value_counts()
print(country_count)

# 绘制每个出品地的电视剧数量的柱状图
plt.figure(figsize=(20,6)) #设置图形的大小 单位英寸
plt.bar(country_count.index, country_count.values)
plt.xlabel("出品地")
plt.ylabel("电视剧数量")
plt.title("每个出品地的电视剧数量")
plt.tight_layout()# 调整间距
plt.show()

# 计算每个类型的电视剧数量
# 这里你需要先将类型列展开，然后再计数
type_count = df["类型"].explode().value_counts()
print(type_count)

# 绘制每个类型的电视剧数量的饼图
plt.pie(type_count.values, labels=type_count.index, autopct="%1.1f%%")
plt.title("每个类型的电视剧数量")
plt.show()

# 计算每个电视剧的短评数和评分的相关系数
corr = df["短评数"].corr(df["rate"])
print(f"每个电视剧的短评数和评分的相关系数是{corr:.2f}")

# 绘制每个电视剧的短评数和评分的散点图
plt.scatter(df["短评数"], df["rate"])
plt.xlabel("短评数")
plt.ylabel("评分")
plt.title("每个电视剧的短评数和评分的散点图")
plt.show()


# 分析不同出品地的电视剧的评分分布  显示不正确
# 使用matplotlib的boxplot函数，可以绘制箱线图，显示每个出品地的电视剧的评分的最大值，最小值，中位数，四分位数和异常值
# 设置x轴为出品地，y轴为评分，data为数据框，order为出品地的排序，palette为颜色
# 为了保持和seaborn的boxplot函数一致的效果，需要设置一些参数，如patch_artist=True, showmeans=True等
plt.boxplot([df[df["出品地"] == "中国大陆"]["rate"], # 中国大陆的评分
             df[df["出品地"] == "美国"]["rate"], # 美国的评分
             df[df["出品地"] == "英国"]["rate"], # 英国的评分
             df[df["出品地"] == "日本"]["rate"], # 日本的评分
             df[df["出品地"] == "韩国"]["rate"], # 韩国的评分
             df[df["出品地"] == "其他"]["rate"]], # 其他的评分
            labels=["中国大陆", "美国", "英国", "日本", "韩国", "其他"], # 设置x轴的标签
            patch_artist=True, # 填充箱体的颜色
            showmeans=True, # 显示均值
            boxprops={"facecolor": "C0", "edgecolor": "grey", "linewidth": 0.5}, # 设置箱体的属性，如颜色，边框，线宽等
            medianprops={"color": "k", "linewidth": 0.5}, # 设置中位数的属性，如颜色，线宽等
            meanprops={'marker':'+', 'markerfacecolor':'k', 'markeredgecolor':'k', 'markersize':5}, # 设置均值的属性，如标记，颜色，大小等
            flierprops={'markerfacecolor': 'C1', 'marker': 'o','markersize': 3.0,'markeredgecolor': 'C1'}, # 设置异常值的属性，如标记，颜色，大小等
            widths=0.5 # 设置箱体的宽度
            )

# 设置y轴的标签
plt.ylabel("评分")
# 设置标题
plt.title("不同出品地的电视剧的评分分布")

# 显示图形
plt.show()

def calculate_statistics(df, column):
    # 计算给定列的均值、标准差、中位数、最小值、最大值
    mean = np.mean(df[column])
    std = np.std(df[column])
    median = np.median(df[column])
    min_value = np.min(df[column])
    max_value = np.max(df[column])
    print(f"{column}的均值是{mean:.2f}")
    print(f"{column}的标准差是{std:.2f}")
    print(f"{column}的中位数是{median:.2f}")
    print(f"{column}的最小值是{min_value:.2f}")
    print(f"{column}的最大值是{max_value:.2f}")

# 计算电视剧的评分的各项统计量
calculate_statistics(df, "rate")

# 使用df.describe()方法获取数据集的基本描述信息
desc_stats = df.describe()
print(desc_stats)

# 可视化描述性统计信息
plt.figure(figsize=(10, 10))

# 绘制箱线图
sns.boxplot(data=desc_stats, orient="h")
plt.title("描述性统计信息的箱线图")
plt.show()



# 选择几个类型作为示例
types = ["爱情", "悬疑", "喜剧", "历史"]

# 对每个类型的电视剧按照出品时间进行分组，计算每年的平均评分
type_rate = pd.DataFrame()
for t in types:
    # 筛选出该类型的电视剧
    df_t = df[df["类型"].apply(lambda x: t in x)]
    # 按照出品时间分组，计算平均评分
    rate_t = df_t.groupby("出品时间")["rate"].mean()
    # 将结果添加到新的DataFrame中
    type_rate[t] = rate_t

# 使用pandas的plot方法绘制折线图
type_rate.plot(kind="line")
plt.xlabel("年份")
plt.ylabel("评分")
plt.title("不同类型的电视剧的评分变化趋势")
plt.legend(types)
plt.show()





# # 定义一个函数，将y轴的值除以10，然后加上'x10'的后缀
# def y_formatter(y, pos):
#     return '{}x10'.format(int(y/10))
#
# # 创建一个FuncFormatter对象，传入上面定义的函数
# y_formatter = FuncFormatter(y_formatter)

countries = ["中国", "美国", "日本", "韩国"]

# 对每个出品地的电视剧按照出品时间进行分组，计算每年的数量
country_count = pd.DataFrame()
for c in countries:
    # 筛选出该出品地的电视剧
    df_c = df[df["出品地"] == c]
    # 按照出品时间分组，计算数量
    count_c = df_c.groupby("出品时间")["电视剧"].count()

    # 将结果添加到新的DataFrame中
    country_count[c] = count_c

# 使用matplotlib的plot函数绘制折线图
for c in countries:
    plt.plot(country_count.index, country_count[c])
plt.xlabel("年份")
plt.ylabel("数量")
plt.title("不同出品地的电视剧的数量变化趋势")
plt.legend(countries)

# 显示图表
plt.show()